package gov.nist.ssd.swqb.core.search;

import java.security.InvalidParameterException;
import java.util.Formatter;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.reasoner.IllegalParameterException;

abstract class AbstractSearch implements Search{  
  
  public static class VarName {
    
    private final String varName;
    
    private VarName(String varName) {
      this.varName = varName;
    }

    public String toString() {
      return varName;
    }
  }
  
  public static class RequestPattern {
    
    private final String requestPattern;
    
    private RequestPattern(String requestPattern) {
      this.requestPattern = requestPattern;
    }
    
    public String toString() {
      return requestPattern;
    }
  }
  
  public static class SearchText {
    
    private final String searchText;
    
    protected SearchText(String searchText) {
      this.searchText = searchText;
    }
    
    public String toString() {
      return searchText;
    }
  }
  
  public static class ExactMatchText extends SearchText{

    protected ExactMatchText(String searchText) {
      super(searchText);
    }
  }
  
  public static class LuceneMatchText extends SearchText {
    
    protected LuceneMatchText(String searchText) {
      super(searchText);
    }
  }
  
  public static class RegexMatchText extends SearchText {
    
    protected RegexMatchText(String searchText) {
      super(searchText);
    }
  }
  
  public static VarName varName(String varName) {
    return new VarName(varName);
  }
  
  public static RequestPattern requestPattern(String requestPattern) {
    return new RequestPattern(requestPattern);
  }
  
  public static ExactMatchText exactMatchText(String exactMatchText) {
    return new ExactMatchText(exactMatchText);
  }
  
  public static LuceneMatchText luceneMatchText(String luceneMatchText) {
    return new LuceneMatchText(luceneMatchText);
  }
  
  public static RegexMatchText regexMatchText(String regexMatchText) {
    return new RegexMatchText(regexMatchText);
  }
  
  public static RequestPattern searchPattern(String searchPattern){
    return new RequestPattern(searchPattern);
  }
  
	private final Model model;
	private final int requestsSize;
	private final VarName varName;
	private String baseQuery;
	
	protected AbstractSearch(SearchText searchText,
	                         Model model,
	                         int requestsSize,
	                         VarName varName,
	                         RequestPattern searchPattern) {
		if(model == null)
			throw new IllegalParameterException("null Model is not allowed.");
		
		if(requestsSize <=0) {
			throw new InvalidParameterException("null or negative requestsSize not allowed");
    }
 
		this.requestsSize = requestsSize;
		this.model = model;
		this.varName = varName;
		
		// build baseQuery
	  StringBuffer sb = new StringBuffer();
	  Formatter f = new Formatter(sb);
	  
	  f.format(searchPattern.toString(), searchText.toString());
	  
	  baseQuery = sb.toString();
	}
	
	@Override
	public boolean isValid() {
	  return true;
	}
	
	@Override
	public String getErrorDescription() {
	  return "";
	}
	
	protected Search getOuter() {
	  return this;
	}
	
	protected int getResSize() {
	  return requestsSize;
	}
	
	protected VarName getVarName() {
	  return varName;
	}
	
	protected Model getModel() {
	  return model;
	}
	
	protected String getBaseQuery() {
	  return baseQuery;
	}
}
